/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "S_模型.h"

#include "../../S_摄像机.h"
#include "../../../底层绘图/底层绘图框架.h"



S_模型::S_模型(uint32 key, S_Mesh* mesh) : S_物体(E_物体类型::t_网格, key) {
	if (!mesh) {
		//m_网格 = f_创建网格对象(0, E_网格数据枚举::e_Mesh_CUDA);
		//m_网格->m_板载缓存 = f_创建板载缓存(E_绘图API::E_Vulkan);
		//f_构建网格板载内存(m_网格, E_绘图API::E_Vulkan);
	} else {
		m_网格 = mesh;
	}
	//m_GPU参数 = 0;
	m_线宽 = 1.0f;
}

S_模型::~S_模型()
{
}



void S_模型::f_set位置(const vec3* xyz, uint32 num) {

}

void S_模型::f_Update(S_渲染参数& c) {
	C_Mat44 mat = C_Mat44::kIdentity;

	auto rx = f_构建旋转矩阵(m_变换.rotation.x, E_轴向::e_X);
	auto ry = f_构建旋转矩阵(m_变换.rotation.y, E_轴向::e_Y);
	auto rz = f_构建旋转矩阵(m_变换.rotation.z, E_轴向::e_Z);
	
	auto s = f_构建缩放矩阵(m_变换.scale);
	
	mat *= f_构建移动矩阵(m_变换.location);
	
	mat *= rz;
	mat *= ry;
	mat *= rx;
	
	mat *= s;
	
	
	//f_copy板载缓存array((S_板载缓存*)m_变换矩阵, m_实例ID, (Mat44f*)&mat, 1);
	
	if (m_UpdateGPU参数布局) {
		m_网格->m_Material->mf_GPU材质槽更新(m_网格->m_Material, m_网格->m_GPU参数布局, 2);

		m_网格->m_GPU参数布局.m_参数槽[0] = (S_板载缓存*)c.m_视图投影矩阵;
		//m_网格->m_GPU参数布局.m_参数槽[1] = (S_板载缓存*)m_变换矩阵;

		m_UpdateGPU参数布局 = false;
	}

}


void S_模型::f_绘制(S_渲染参数& 参数) {
	S_渲染参数 渲染参数 = 参数;
	//渲染参数.m_视图投影矩阵 = c.m_视图投影矩阵;

	/*f_setGPU参数布局(
		m_网格->m_Material->m_Shader,
		m_网格->m_Material->m_GPU参数set,
		渲染参数
	);

	渲染参数.m_GPU参数 = m_网格->m_GPU参数布局.m_GPU参数set;
	渲染参数.m_实例数量 = m_实例数量;
	渲染参数.m_线宽 = m_线宽;

	m_网格->f_绘制(渲染参数);*/
}


void S_模型::f_set矩阵(const Mat44f* mat) {
	//f_buf_fill板载缓存((S_板载缓存*)m_变换矩阵, mat, m_实例ID);
}

void S_模型::f_set矩阵mt(const Mat44f* mat) {
	//((Mat44f*)(((S_板载缓存*)m_变换矩阵)->m_mappedPtr))[m_实例ID] = *mat;
}

std::vector<S_物体*> S_模型::f_创建实例(uint32 num) {
	//auto* buf = ((S_板载缓存*)m_变换矩阵);
	//uint32 offset = buf->m_Size;

	//m_实例数量 = offset + num;
	//f_buf_resize(buf, m_实例数量, E_板载缓存类型::e_SSBO);

	std::vector<S_物体*> objs(num);
	for (uint16 i = 0; i < num; ++i) {
		S_模型* obj = new S_模型(m_Type, 0);
		obj->m_网格 = m_网格;
		obj->m_变换矩阵 = m_变换矩阵;
		//obj->m_实例ID = offset + i;
		//obj->m_Material
		obj->m_Name = m_Name + L"." + f_整数值转宽字符串(obj->m_实例ID);
		objs[i] = obj;
	}

	m_UpdateGPU参数布局 = true;

	return objs;
}



/*void S_模型::f_updateGPU参数布局() {
	if (m_UpdateGPU参数布局) {
		//m_网格->m_Material->f_updateGPU参数布局(m_GPU参数布局, 2);

		//m_GPU参数布局.m_参数槽[0] = 0;
		m_GPU参数布局.m_参数槽[1] = (S_板载缓存*)m_变换矩阵;

		f_setGPU参数布局(
			m_网格->m_Material->m_Shader,
			m_GPU参数布局.m_GPU参数set,
			m_GPU参数布局.m_参数槽,
			m_GPU参数布局.m_参数数量,
			m_GPU参数布局.m_纹理槽,
			m_GPU参数布局.m_纹理数量
		);

		m_UpdateGPU参数布局 = false;
	}
}*/










/*S_GL立即绘制模型::S_GL立即绘制模型(uint32 key) : S_物体(E_物体数据::t_网格, key) {

}

S_GL立即绘制模型::~S_GL立即绘制模型()
{
}

void S_GL立即绘制模型::f_set位置(const vec3* xyz, uint32 num)
{
}

void S_GL立即绘制模型::f_Update(S_渲染参数& c) {
	C_Mat44 mat = C_Mat44::kIdentity;

	auto rx = f_构建旋转矩阵(m_变换.rotation.x, E_轴向::e_X);
	auto ry = f_构建旋转矩阵(m_变换.rotation.y, E_轴向::e_Y);
	auto rz = f_构建旋转矩阵(m_变换.rotation.z, E_轴向::e_Z);
	
	auto s = f_构建缩放矩阵(m_变换.scale);


	mat *= f_构建移动矩阵(m_变换.location);
	//mat *= r;

	mat *= rz;
	mat *= ry;
	mat *= rx;

	mat *= s;


	f_copy板载缓存array((S_板载缓存*)m_变换矩阵, m_实例ID, (Mat44f*)&mat, 1);
	
	if (m_UpdateGPU参数布局) {
		m_网格->m_Material->mf_GPU参数布局更新(m_网格->m_Material, m_GPU参数布局, 2);

		m_GPU参数布局.m_参数槽[0] = (S_板载缓存*)c.m_视图投影矩阵;
		m_GPU参数布局.m_参数槽[1] = (S_板载缓存*)m_变换矩阵;

		f_setGPU参数布局(
			m_网格->m_Material->m_Shader,
			m_GPU参数布局.m_GPU参数set,
			m_GPU参数布局.m_参数槽,
			m_GPU参数布局.m_参数数量,
			m_GPU参数布局.m_纹理槽,
			m_GPU参数布局.m_纹理数量
		);

		m_UpdateGPU参数布局 = false;
	}

}

void S_GL立即绘制模型::f_绘制(S_渲染参数& 参数) {
	S_渲染参数 渲染参数 = 参数;
	
	渲染参数.m_GPU参数 = m_GPU参数布局.m_GPU参数set;
	渲染参数.m_实例数量 = m_实例数量;
	渲染参数.m_线宽 = m_线宽;

	m_网格->f_绘制(渲染参数);
}

void S_GL立即绘制模型::f_set矩阵(const Mat44f* mat) {
	f_fill板载缓存((S_板载缓存*)m_变换矩阵, mat, m_实例ID);
}

void S_GL立即绘制模型::f_set矩阵mt(const Mat44f* mat) {
	((Mat44f*)(((S_板载缓存*)m_变换矩阵)->m_mappedPtr))[m_实例ID] = *mat;
}*/




